﻿using Coldairarrow.Entity.Base;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.IT;
using Coldairarrow.Entity.PB;
using Coldairarrow.Entity.TD;
using Coldairarrow.IBusiness;
using Coldairarrow.IBusiness.DTO;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.Base
{
    public partial class Base_RepairOrderBusiness : BaseBusiness<Base_RepairOrder>, IBase_RepairOrderBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IOperatorDept _opdept;
        public Base_RepairOrderBusiness(IDbAccessor db, IOperator @operator, IOperatorDept @opdept)
            : base(db)
        {
            _operator = @operator;
            _opdept = @opdept;
        }

        #region 外部接口

        public async Task<PageResult<Base_RepairOrder>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<Base_RepairOrder>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<Base_RepairOrder, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<Base_RepairOrder> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }
        public async Task<Base_RepairOrder> GetTheDataAsyncQQQ(string id)
        {
            var Q = await Db.GetIQueryable<Base_RepairOrder>().Where(m => m.Id == id).FirstOrDefaultAsync();
            return Q;
        }
        public async Task AddDataAsync(Base_RepairOrder data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(Base_RepairOrder data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        /// <summary>
        /// 保存维修工单主表·字表数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task AddDataList(Base_Base_RepairOrderlistinfo data)
        {
            Base_RepairOrder base_RepairOrder = new Base_RepairOrder
            {
                Id = data.Id,//编号
                UserId = data.UserId,
                Parentid = data.Id,
                CompletionTime = data.CompletionTime,
                Type = data.Type,
                MaintenancePrice = data.MaintenancePrice,
                FaultAnalysis = data.FaultAnalysis,
                CreateTime = DateTime.Now,
                Deleted = false,
                CreatorId = data.CreatorId,
                MaintenanceLevel = data.MaintenanceLevel,
                DeviceId = data.DeviceId,
                QrCode = base_RepairOrderCode + "," + data.Id
            };

            await Db.InsertAsync(base_RepairOrder);
            var aa = base_RepairOrder.Parentid;
            string sqlMain = "";
            sqlMain += @" Update  Base_RepairOrderApply set States=1 where Id='" + aa + "'; ";
            await ExecuteSqlAsync(sqlMain);
            var base_RepairOrderDetails = data.SubData.Select(x => new Base_RepairOrderDetails
            {
                Id = IdHelper.GetId(),
                ParentId = data.Id,
                QrCode = base_RepairOrderDetailsCode + "," + x.Id,
                MaterialId = x.MaterialId,
                Nums = x.Nums,
                CreateTime = DateTime.Now,
                CreatorId = data.CreatorId,
                Deleted = false,
                LocalMaterialId = x.Id,
            }).ToList();
            foreach (var item in base_RepairOrderDetails)
            {
                item.QrCode = base_RepairOrderDetailsCode + "," + item.Id;

            }
            await Db.InsertAsync(base_RepairOrderDetails);
        }

        /// <summary>
        /// 编辑操作
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task UpdateDataList(Base_Base_RepairOrderlistinfo data)
        {
            //删除明细信息
            await ExecuteSqlAsync(" delete from Base_RepairOrderDetails where ParentId='" + data.Id + "'");
            var addDetail = data.SubData.Select(x => new Base_RepairOrderDetails
            {
                Id = IdHelper.GetId(),//id
                ParentId = data.Id,//主表信息
                MaterialId = x.MaterialId,//物料编号
                Nums = x.Nums,
                CreateTime = DateTime.Now,
                CreatorId = data.CreatorId,
                LocalMaterialId = x.LocalMaterialId,
                Deleted = false,
            }).ToList();
            foreach (var item in addDetail)
            {
                item.QrCode = base_RepairOrderDetailsCode + "," + item.Id;
            }
            await Db.InsertAsync<Base_RepairOrderDetails>(addDetail);

        }
        #region
        /// <summary>
        /// 维修领药
        /// </summary>
        /// <param name="RepairOrderQrCode">维修单二维码</param>
        /// <returns></returns>
        public async Task<Base_RepairOrderDetailsPDADTO> GetPDADataListInfo(string RepairOrderQrCode)
        {
            Base_User bdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            string[] QrCode = RepairOrderQrCode.Split(',');
            string Herder = QrCode[0].ToString();
            //判断扫描请求头
            if (Herder == "38")
            {
                Expression<Func<Base_RepairOrderDetails, PB_Material, Base_RepairOrder, Base_User, Base_RepairOrderDetailsPDADTO>> select = (a, b, c, d) => new Base_RepairOrderDetailsPDADTO
                {
                    MaterialIdName = b.Name,
                    RealName = d.RealName,
                };
                select = select.BuildExtendSelectExpre();
                var q = from a in Db.GetIQueryable<Base_RepairOrderDetails>().AsExpandable()
                        join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        join c in Db.GetIQueryable<Base_RepairOrder>() on a.ParentId equals c.Id into ac
                        from c in ac.DefaultIfEmpty()
                        join d in Db.GetIQueryable<Base_User>() on c.UserId equals d.Id into cd
                        from d in cd.DefaultIfEmpty()
                        select @select.Invoke(a, b, c, d);
                Base_RepairOrderDetailsPDADTO listData = await q.Where(m => m.QrCode == RepairOrderQrCode).FirstOrDefaultAsync();

                return listData;

            }
            else
            {
                throw new BusException("请扫描或输入正确的维修单二维码信息");
            }
        }
        /// <summary>
        /// pda 扫码获取维修单数据
        /// </summary>
        /// <param name="RepairOrderQrCode"></param>
        /// <returns></returns>
        public async Task<Base_RepairOrPDADTO> GetPDADataListMain(string RepairOrderQrCode)
        {

            Base_User bdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            string[] QrCode = RepairOrderQrCode.Split(',');
            string Herder = QrCode[0].ToString();
            var Id = QrCode[1].ToString();
            var Data = await Db.GetIQueryable<Base_RepairOrderApply>().Where(m => m.Id == Id).FirstOrDefaultAsync();
            if (Data.States == 3)
            {
                throw new BusException("该维修单已完成");
            }
            //判断扫描请求头
            if (Herder == "37")
            {
                Expression<Func<Base_RepairOrder, Base_User, Base_Device, Base_RepairOrPDADTO>> select = (a, b, c) => new Base_RepairOrPDADTO
                {

                    RealName = b.RealName,
                    DeviceName = c.Name,
                };
                select = select.BuildExtendSelectExpre();
                var q = from a in Db.GetIQueryable<Base_RepairOrder>().AsExpandable()
                        join b in Db.GetIQueryable<Base_User>() on a.UserId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        join c in Db.GetIQueryable<Base_Device>() on a.DeviceId equals c.Id into ac
                        from c in ac.DefaultIfEmpty()
                        select @select.Invoke(a, b, c);
                Base_RepairOrPDADTO listData = await q.Where(m => m.QrCode == RepairOrderQrCode).FirstOrDefaultAsync();
                if (listData==null) {
                    throw new BusException("维修单号不存在!"+ QrCode[1].ToString());
                }
                if (bdata.RealName != listData.RealName)
                {
                    throw new BusException("维修单派工单姓名不符!");
                }
                else
                {
                    return listData;
                }
            }
            else
            {
                throw new BusException("请扫描或输入正确的维修单二维码信息");
            }
        }

        /// <summary>
        /// PDA维修单扫码物料
        /// </summary>
        /// <param name="RepairOrderCode">维修单号</param>
        /// <param name="MaterialCode">物料二维码</param>
        /// <returns></returns>
        public async Task<Base_RepairOrderDetailsPDADTO> GetRepairOrderDetailsPDANumber(string RepairOrderCode, string MaterialCode)
        {
            var packmodel = MaterialCode.Split(',')?[0];
            string MaterialId = string.Empty;
            if (packmodel == "04")
            {
                var model = MaterialCode.Split(',');
                if (model.Length > 2)
                {
                    if (model.Length < 4)
                    {
                        throw new BusException("请扫描物料二维码或手动输入");
                    }
                    else
                    {
                        MaterialId = model?[3].ToString();
                    }
                }
                else
                {
                    MaterialId = model?[1].ToString();
                }
            }
            if (!MaterialId.IsNullOrEmpty())
            {
                Expression<Func<Base_RepairOrderDetails, PB_Material, Base_RepairOrderDetailsPDADTO>> select = (a, b) => new Base_RepairOrderDetailsPDADTO
                {
                    MaterialIdName = b.Name,
                    MaterialIdSpec = b.Spec,
                    MaterialIdCode = b.Code,
                };
                select = select.BuildExtendSelectExpre();
                var q = from a in Db.GetIQueryable<Base_RepairOrderDetails>().AsExpandable()
                        join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        select @select.Invoke(a, b);
                Base_RepairOrderDetailsPDADTO listData = await q.Where(m => m.ParentId == RepairOrderCode && m.MaterialId == MaterialId).FirstOrDefaultAsync();
                return listData;
            }
            else
            {
                throw new BusException("请输入物料编码");
            }
        }

        /// <summary>
        /// PDA 点击确定操作  朱庆龙   2022/18:02/
        /// </summary>
        /// <param name="data">
        /// RepairOrderId 维修单明细二维码
        /// </param>
        /// <returns></returns>
        [Transactional]
        public async Task UpdateStockUpDataAsync(UpdateInventory data)
        {
      
            string packid = string.Empty;
            string materialId =data.MaterialId;
            string packmodel = string.Empty;
            string locaId = data.LocationId;
           if (materialId.Split(',')[0].ToString() == "04")
            {
                var model = data.MaterialId.Split(',');
                if (model.Length > 2)
                {
                    materialId = model?[3].ToString();
                }
                else
                {
                    materialId = model?[1].ToString();
                }
            }
            List<IT_LocalDetail> IT_LocalDetaillist = await Db.GetIQueryable<IT_LocalDetail>().Where(x => x.MaterialId == materialId && x.PackId == "" && x.LocalId == locaId).ToListAsync();
            if (IT_LocalDetaillist.Count > 0)
            {
                //汇总当前货位的物料总数量
                var matersumnums = IT_LocalDetaillist.GroupBy(x => new { x.MaterialId, x.StorId, x.LocalId }).Select(x => new { MaterialId = x.Key.MaterialId, LocalId = x.Key.LocalId, StorId = x.Key.StorId, materNums = x.Sum(i => i.Num) }).FirstOrDefault();
                //数量对比 不满足return
                if (data.Nums > matersumnums.materNums)
                {
                    throw new Exception("请确定当前货位物料数量 是否满足出库数量");
                }
                //获取要出库的单个物料数量
                double? warehouseNum = data.Nums;
                string itsql = string.Empty;
                string strLocalId = string.Empty;
                string strStorId = string.Empty;
                string stockupQrCode = data.RepairOrderId; //维修单明细id
                foreach (var item in IT_LocalDetaillist)
                {
                    if (warehouseNum > 0)
                    {
                        strLocalId = item.LocalId;
                        strStorId = item.StorId;
                        //出库数量等于库存明细数量时
                        if (item.Num == warehouseNum)
                        {
                            warehouseNum -= item.Num;
                            if (item.OldOrNew == 0)
                            {
                                itsql += @" update IT_LocalMaterial set Nums_O=IFNULL(Nums_O,0)-" + item.Num + ",ScanNum=IFNULL(ScanNum,0)-" + item.Num + " where StorId='" + item.StorId + "' and LocalId='" + item.LocalId + "' and MaterialId='" + item.MaterialId + "'; ";
                            }
                            else if (item.OldOrNew == 1)
                            {
                                itsql += @" update IT_LocalMaterial set Nums_N=IFNULL(Nums_N,0)-" + item.Num + ",ScanNum=IFNULL(ScanNum,0)-" + item.Num + " where StorId='" + item.StorId + "' and LocalId='" + item.LocalId + "' and MaterialId='" + item.MaterialId + "'; ";
                            }
                            itsql += @" delete from IT_LocalDetail where Id='" + item.Id + "'; ";

                        }
                        else if (item.Num < warehouseNum)//出库数量大于库存明细数量时
                        {
                            if (warehouseNum >= item.Num)
                            {
                                warehouseNum -= item.Num;
                                if (item.OldOrNew == 0)
                                {
                                    itsql += @" update IT_LocalMaterial set Nums_O=IFNULL(Nums_O,0)-" + item.Num + ",ScanNum=IFNULL(ScanNum,0)-" + item.Num + " where StorId='" + item.StorId + "' and LocalId='" + item.LocalId + "' and MaterialId='" + item.MaterialId + "'; ";
                                }
                                else if (item.OldOrNew == 1)
                                {
                                    itsql += @" update IT_LocalMaterial set Nums_N=IFNULL(Nums_N,0)-" + item.Num + ",ScanNum=IFNULL(ScanNum,0)-" + item.Num + " where StorId='" + item.StorId + "' and LocalId='" + item.LocalId + "' and MaterialId='" + item.MaterialId + "'; ";
                                }
                                itsql += @" delete from IT_LocalDetail where Id='" + item.Id + "'; ";
                            }
                            else
                            {
                                warehouseNum -= warehouseNum;
                                if (item.OldOrNew == 0)
                                {
                                    itsql += @" update IT_LocalMaterial set Nums_O=IFNULL(Nums_O,0)-" + warehouseNum + ",ScanNum=IFNULL(ScanNum,0)-" + warehouseNum + " where StorId='" + item.StorId + "' and LocalId='" + item.LocalId + "' and MaterialId='" + item.MaterialId + "'; ";
                                }
                                else if (item.OldOrNew == 1)
                                {
                                    itsql += @" update IT_LocalMaterial set Nums_N=IFNULL(Nums_N,0)-" + warehouseNum + ",ScanNum=IFNULL(ScanNum,0)-" + warehouseNum + " where StorId='" + item.StorId + "' and LocalId='" + item.LocalId + "' and MaterialId='" + item.MaterialId + "'; ";
                                }
                                itsql += @" update IT_LocalDetail set Num=IFNULL(Num,0)-" + warehouseNum + " where Id='" + item.Id + "'; ";
                            }
                        }
                        else if (item.Num > warehouseNum) //出库数量小于库存明细数量时
                        {
                            item.Num -= warehouseNum;
                            if (item.OldOrNew == 0)
                            {
                                itsql += @" update IT_LocalMaterial set Nums_O=IFNULL(Nums_O,0)-" + warehouseNum + ",ScanNum=IFNULL(ScanNum,0)-" + warehouseNum + " where StorId='" + item.StorId + "' and LocalId='" + item.LocalId + "' and MaterialId='" + item.MaterialId + "'; ";
                            }
                            else if (item.OldOrNew == 1)
                            {
                                itsql += @" update IT_LocalMaterial set Nums_N=IFNULL(Nums_N,0)-" + warehouseNum + ",ScanNum=IFNULL(ScanNum,0)-" + warehouseNum + " where StorId='" + item.StorId + "' and LocalId='" + item.LocalId + "' and MaterialId='" + item.MaterialId + "'; ";
                            }
                            itsql += @" update IT_LocalDetail set Num=IFNULL(Num,0)-" + warehouseNum + " where Id='" + item.Id + "'; ";
                            warehouseNum -= warehouseNum;
                        }

                    }
                    else
                    {
                        continue;
                    }
                }
                   await ExecuteSqlAsync(itsql);
                //获取要出库的单个物料数量
                warehouseNum = data.Nums;
                itsql = "";
                strLocalId = "";
                strStorId = "";
             
                List<PB_Stock> PB_Stocklist = await Db.GetIQueryable<PB_Stock>().Where(x => x.MaterialId == materialId && x.PackId == "" && x.LocationId == locaId).ToListAsync();
                if (PB_Stocklist.Count > 0)
                {
                    foreach (var item in PB_Stocklist)
                    {
                        if (warehouseNum != 0)
                        {
                            strLocalId = item.LocationId;
                            strStorId = item.StorId;
                            //出库数量等于库存明细数量时
                            if (item.StockNumber == warehouseNum)
                            {
                                warehouseNum -= item.StockNumber;
                                itsql += @" delete from PB_Stock where Id='" + item.Id + "'; ";
                            }
                            else if (item.StockNumber < warehouseNum)   //出库数量大于库存明细数量时
                            {
                                if (warehouseNum >= item.StockNumber)
                                {
                                    warehouseNum -= item.StockNumber;
                                    itsql += @" delete from PB_Stock where Id='" + item.Id + "'; ";
                                }
                                else
                                {
                                    warehouseNum -= warehouseNum;
                                    itsql += @" update PB_Stock set StockNumber=IFNULL(StockNumber,0)-" + warehouseNum + " where Id='" + item.Id + "'; ";
                                }
                            }
                            else if (item.StockNumber > warehouseNum) //出库数量小于库存明细数量时
                            {
                                item.StockNumber -= warehouseNum;
                                itsql += @" update PB_Stock set StockNumber=IFNULL(StockNumber,0)-" + warehouseNum + " where Id='" + item.Id + "'; ";
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    await ExecuteSqlAsync(itsql);
                }
                Base_RepairOrderDetails pickupdata = await Db.GetIQueryable<Base_RepairOrderDetails>().Where(x => x.Id == stockupQrCode).FirstOrDefaultAsync();
                //增加维修单明细日志
                Base_RepairOrderLoadList pbdata = new Base_RepairOrderLoadList();
                pbdata.Id = IdHelper.GetId();
                pbdata.ParentId = pickupdata.Id; //维修单明细
                pbdata.LocalId = strLocalId;
                pbdata.PackId = "";
                pbdata.MaterialId = materialId;
                pbdata.Nums = data.Nums;
                pbdata.CreatorId = _operator.UserId;
                pbdata.CreatorRealName = _operator.UserName;
                pbdata.CreateTime = DateTime.Now;
                pbdata.Deleted = false;
                pbdata.State = 1;
                await Db.InsertAsync<Base_RepairOrderLoadList>(pbdata);
                //增加出库日志
                PB_StockLog pblog = new PB_StockLog();
                pblog.Id = IdHelper.GetId();
                pblog.PackId = packid;
                pblog.StorId = strStorId;
                pblog.LocationId = strLocalId;
                pblog.MaterialId = materialId;
                pblog.StockNumber = data.Nums;
                pblog.CreatorId = _operator.UserId;
                pblog.CreatorName = _operator.UserName;
                pblog.OperatorId = _operator.UserId;
                pblog.Type = 1;
                pblog.OrderID = stockupQrCode;
                pblog.CreateTime = DateTime.Now;
                pblog.State = 1;
            } 
            else
                {
                    throw new BusException("请检查货位上的库存物料是否满足需求");
                }

            #endregion
            #endregion

          

        }

        /// <summary>
        /// 移除操作
        /// </summary>
        /// <param name="stockupQrCode"></param>
        /// <param name="packqrocde"></param>
        /// <param name="nums"></param>
        /// <returns></returns>
        public async Task DeleteStockUpDetailListDataAsync(string stockupQrCode, string MaterialId, double nums)
        {


            Base_User bdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            string materialId = MaterialId;
            string stockupid = stockupQrCode;   //维修单明细单id
            string packmodel = string.Empty;
            string packid = string.Empty;
            int State = 1;
            if (materialId.Split(',')[0].ToString() == "04")
            {
                var model = MaterialId.Split(',');
                if (model.Length > 2)
                {
                    materialId = model?[3].ToString();
                }
                else
                {
                    materialId = model?[1].ToString();
                }
            }
            Base_RepairOrderDetails RepairOrderDetails = await Db.GetIQueryable<Base_RepairOrderDetails>().Where(x => x.Id == stockupid).FirstOrDefaultAsync();
            string sqlMain = string.Empty;
            Expression<Func<Base_RepairOrderLoadList, PB_Location, Base_RepairOrderDetails, PB_Material, Base_RepairOrderLoadListDTO>> packselect = (a, b, c, d) => new Base_RepairOrderLoadListDTO
            {
                LocationId = b.Id,
                StorId = b.StorId,
                AreaId = b.AreaId,
                RackId = b.RackId,
                MeasureId = d.storageId,
            };
            packselect = packselect.BuildExtendSelectExpre();
            var packdata = from a in Db.GetIQueryable<Base_RepairOrderLoadList>().AsExpandable()
                           join b in Db.GetIQueryable<PB_Location>() on a.LocalId equals b.Id into ab
                           from b in ab.DefaultIfEmpty()
                           join c in Db.GetIQueryable<Base_RepairOrderDetails>() on a.ParentId equals c.Id into ac
                           from c in ac.DefaultIfEmpty()
                           join d in Db.GetIQueryable<PB_Material>() on a.MaterialId equals d.Id into ad
                           from d in ad.DefaultIfEmpty()
                           select @packselect.Invoke(a, b, c, d);
            var unloaddata = await packdata.Where(x => x.ParentId == stockupid && x.MaterialId == materialId && x.State ==State ).FirstOrDefaultAsync(); //删除派工单备货出库的明细
            sqlMain += @" delete from Base_RepairOrderLoadList where MaterialId='" + unloaddata.MaterialId + "' and ParentId='" + unloaddata.ParentId + "' and LocalId='" + unloaddata.LocationId + "' and Nums='" + nums + "' and State= 1  LIMIT 1; ";
            await ExecuteSqlAsync(sqlMain);
            PB_Stock stockdata = new PB_Stock();
            stockdata.Id = IdHelper.GetId();
            stockdata.PackId = packid;
            stockdata.StorId = unloaddata.StorId;
            stockdata.LocationId = unloaddata.LocationId;
            stockdata.StockNumber = nums;
            stockdata.MaterialId = unloaddata.MaterialId;
            stockdata.CreatorId = _operator.UserId;
            stockdata.CreatorName = bdata.RealName;
            stockdata.CreateTime = DateTime.Now;
            stockdata.OperatorId = _operator.UserId;
            stockdata.Type = 2;
            stockdata.OrderID = stockupid;
            stockdata.OldOrNew = 1;
            stockdata.AreaId = unloaddata.AreaId;
            stockdata.RackId = unloaddata.RackId;
            await Db.InsertAsync<PB_Stock>(stockdata);
            PB_StockLog stockdatalog = new PB_StockLog();
            stockdatalog.Id = IdHelper.GetId();
            stockdatalog.PackId = packid;
            stockdatalog.StorId = unloaddata.StorId;
            stockdatalog.LocationId = unloaddata.LocationId;
            stockdatalog.StockNumber = nums;
            stockdatalog.MaterialId = unloaddata.MaterialId;
            stockdatalog.CreatorId = _operator.UserId;
            stockdatalog.CreatorName = bdata.RealName;
            stockdatalog.CreateTime = DateTime.Now;
            stockdatalog.OperatorId = _operator.UserId;
            stockdatalog.Type = 2;
            stockdatalog.OrderID = stockupid;
            stockdatalog.OldOrNew = 1;
            stockdatalog.State = 0;
            await Db.InsertAsync<PB_StockLog>(stockdatalog);
            IT_LocalDetail itdata = new IT_LocalDetail();
            itdata.Id = IdHelper.GetId();
            itdata.StorId = unloaddata.StorId;
            itdata.LocalId = unloaddata.LocationId;
            itdata.MaterialId = unloaddata.MaterialId;
            itdata.MeasureId = unloaddata.MeasureId;
            itdata.BarCode = MaterialId;
            itdata.InTime = DateTime.Now;
            itdata.CreateTime = DateTime.Now;
            itdata.CreatorId = _operator.UserId;
            itdata.Deleted = false;
            itdata.Num = nums;
            itdata.PackId = packid;
            itdata.OldOrNew = 1;
            itdata.JobId = "";
            await Db.InsertAsync<IT_LocalDetail>(itdata);
            sqlMain = "";
            sqlMain = @" update IT_LocalMaterial set Nums_N=IFNULL(Nums_N,0)+" + nums + ",ScanNum=IFNULL(ScanNum,0)+" + nums + " where MaterialId='" + unloaddata.MaterialId + "' and StorId='" + unloaddata.StorId + "' and LocalId='" + unloaddata.LocationId + "' ";
            await ExecuteSqlAsync(sqlMain);

        }

        /// <summary>
        /// 出库提交
        /// </summary>
        /// <param name="stockupQrCode">派工单二维码</param>
        /// <returns></returns>
        public async Task SubmitStockUpDataAsync(string RefCode,string stockupQrCode)
        {
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            string stockupid = stockupQrCode;
            String[] A = stockupQrCode.Split(',');
            int State = 1;
            List<Base_RepairOrderLoadListDTO> listDTOs = new List<Base_RepairOrderLoadListDTO>();
            foreach (var item in A) {
                Base_RepairOrderLoadListDTO DAT = new Base_RepairOrderLoadListDTO();
                Expression<Func<Base_RepairOrderLoadList, PB_Material, Base_RepairOrderDetails, Base_RepairOrderLoadListDTO>> packselect = (a, b, c) => new Base_RepairOrderLoadListDTO
                {
                    Price = b.Price,
                    LocalId = a.LocalId
                };
                packselect = packselect.BuildExtendSelectExpre();
                var packdata = from a in Db.GetIQueryable<Base_RepairOrderLoadList>().AsExpandable()
                               join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                               from b in ab.DefaultIfEmpty()
                               join c in Db.GetIQueryable<Base_RepairOrderDetails>() on a.ParentId equals c.Id into ac
                               from c in ac.DefaultIfEmpty()
                               select @packselect.Invoke(a, b, c);
                 DAT =await packdata.Where(x => x.ParentId == item && x.State == State).FirstOrDefaultAsync();
                listDTOs.Add(DAT);
            }          
            List<string> listdata = new List<string>();
            string sqlMain = "";
            int indexstate = 0;
            int status = 0;
            status = 3;
            double dbnum = 0;
            string outid = IdHelper.GetId();
            List<TD_OutStorDetail> listdetaildata = new List<TD_OutStorDetail>();
            int i = 0;
            string StorId = string.Empty;
            string AreaId = string.Empty;
            string RackId = string.Empty;
            foreach (var item in listDTOs)
            {
                if (i == 0)
                {
                    var locadata = await Db.GetIQueryable<PB_Location>().Where(x => x.Id == item.LocalId).FirstOrDefaultAsync();
                    StorId = locadata.StorId;
                    AreaId = locadata.AreaId;
                    RackId = locadata.RackId;
                }
                TD_OutStorDetail outdetaildata = new TD_OutStorDetail();
                outdetaildata.Id = IdHelper.GetId();
                outdetaildata.StorId = StorId;
                outdetaildata.OutStorId = outid;
                outdetaildata.LocalId = item.LocalId;
                outdetaildata.AreaId = AreaId;
                outdetaildata.RackId = RackId;
                outdetaildata.MaterialId = item.MaterialId;
                outdetaildata.OutNum = Convert.ToDouble(item.Nums);
                outdetaildata.Price = Convert.ToDouble(item.Price);
                outdetaildata.TotalAmt = Convert.ToDouble(item.Nums) * Convert.ToDouble(item.Price);
                dbnum += Convert.ToDouble(item.Nums);
                outdetaildata.CreatorId = _operator.UserId;
                outdetaildata.CreateTime = DateTime.Now;
                outdetaildata.Deleted = false;
                listdetaildata.Add(outdetaildata);
                i++;
            }
            await Db.InsertAsync<TD_OutStorDetail>(listdetaildata);
            //添加出库明细表
            List<TD_OutStorRecord> listtrecorddata = new List<TD_OutStorRecord>();
            var listd = listdetaildata.GroupBy(x => new { x.StorId, x.LocalId, x.OutStorId, x.MaterialId, x.Price }).Select(x => new { StorId = x.Key.StorId, LocalId = x.Key.LocalId, OutStorId = x.Key.OutStorId, MaterialId = x.Key.MaterialId, Price = x.Key.Price, Nums = x.Sum(n => n.OutNum) });
            foreach (var item in listd)
            {
                TD_OutStorRecord recodata = new TD_OutStorRecord();
                recodata.Id = IdHelper.GetId();
                recodata.StorId = item.StorId;
                recodata.OutStorId = item.OutStorId;
                recodata.MaterialId = item.MaterialId;
                recodata.OutNum = item.Nums;
                recodata.Price = item.Price;
                recodata.TotalAmt = item.Nums * item.Price;
                recodata.CreateTime = DateTime.Now;
                recodata.CreatorId = _operator.UserId;
                recodata.Deleted = false;
                listtrecorddata.Add(recodata);
            }
            await Db.InsertAsync<TD_OutStorRecord>(listtrecorddata);
            var deptdata = await _opdept.GetOperatorDept();
            List<Base_RepairOrderDetailsPDADTO> list = new List<Base_RepairOrderDetailsPDADTO>();
            Expression<Func<Base_RepairOrderDetails, PB_Material, Base_RepairOrder, Base_RepairOrderDetailsPDADTO>> select = (a, b, c) => new Base_RepairOrderDetailsPDADTO
            {
                MaterialIdName = b.Name,
                MaterialIdCode=b.Code,
                MaterialIdSpec=b.Spec,
      
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in Db.GetIQueryable<Base_RepairOrderDetails>().AsExpandable()
                    join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_RepairOrder>() on a.ParentId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                
                    select @select.Invoke(a, b, c);

            var PickUpMainProjectdata = await q.Where(x => x.Id == stockupid).FirstOrDefaultAsync();
            //创建维修领料单
            TD_OutStorage outdata = new TD_OutStorage();
            outdata.Id = outid;
            outdata.Code = DateTime.Now.ToString("yyyyMMddHHmmss");
            outdata.OutTime = DateTime.Now;
            outdata.StorageId = StorId;
            outdata.OutType = "Maintainice"; //Maintainice 维修领料单
            outdata.RefCode = RefCode;
            outdata.ProjectId ="";
            outdata.OutNum = dbnum;
            outdata.CreatorId = _operator.UserId;
            outdata.CreateTime = DateTime.Now;
            outdata.Status = 0;
            outdata.Deleted = false;
            outdata.QrCode = h_OutStorage + "," + outid;
            outdata.DepId = deptdata.DetpId;
            outdata.FactoryId = userdata.FactoryId;
            await Db.InsertAsync<TD_OutStorage>(outdata);
            Expression<Func<Base_RepairOrderLoadList, PB_Material, Base_RepairOrderDetails, Base_RepairOrderLoadListDTO>> selectq = (a, b, c) => new Base_RepairOrderLoadListDTO
            {
                Price = b.Price,
                LocalId = a.LocalId
            };
            selectq = selectq.BuildExtendSelectExpre();
            var qd = from a in Db.GetIQueryable<Base_RepairOrderLoadList>().AsExpandable()
                     join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                     from b in ab.DefaultIfEmpty()
                     join c in Db.GetIQueryable<Base_RepairOrderDetails>() on a.ParentId equals c.Id into ac
                     from c in ac.DefaultIfEmpty()
                     select selectq.Invoke(a, b, c);
            var qdata = qd.Where(x => x.ParentId == stockupid).ToList();

            var listdetdata = qdata.GroupBy(x => new { x.MaterialId, x.Nums, x.LocalId }).Select(x => new { MaterialId = x.Key.MaterialId, StockVolume = x.Key.Nums, LocationId = x.Key.LocalId }).ToList();


            foreach (var id in A) {
                //修改发维修明细日志为已出库
                string sql = @"update Base_RepairOrderLoadList set State= 2 where ParentId='" + id + "';";
                await ExecuteSqlAsync(sql);
            }
        
        }

        /// <summary>
        /// 扫描维修单号获取出库数据
        /// </summary>
        /// <param name="RepairOrderQrCode"></param>
        /// <returns></returns>
        public async Task<Base_RepairOrderOK> GetPDADataListOK(string RepairOrderQrCode)
        {
            Base_RepairOrderOK base_RepairOrderOK = new Base_RepairOrderOK();
            Base_User bdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            string[] QrCode = RepairOrderQrCode.Split(',');
            string Herder = QrCode[0].ToString();
            string RefCode = QrCode[1].ToString();
            //判断扫描请求头
            if (Herder == "37")
            {
                Expression<Func<Base_RepairOrder, Base_User, Base_Device, Base_RepairOrderApply, Base_RepairOrPDADTO>> select = (a, b, c,e) => new Base_RepairOrPDADTO
                {

                    RealName = b.RealName,
                    DeviceName = c.Name,
                    States=e.States,
                };
                select = select.BuildExtendSelectExpre();
                var q = from a in Db.GetIQueryable<Base_RepairOrder>().AsExpandable()
                        join b in Db.GetIQueryable<Base_User>() on a.UserId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        join c in Db.GetIQueryable<Base_Device>() on a.DeviceId equals c.Id into ac
                        from c in ac.DefaultIfEmpty()
                        join e in Db.GetIQueryable<Base_RepairOrderApply>() on a.Parentid equals e.Id into ae
                        from e in ae.DefaultIfEmpty()
                        select @select.Invoke(a, b, c,e);
                Base_RepairOrPDADTO listData = await q.Where(m => m.QrCode == RepairOrderQrCode).FirstOrDefaultAsync();
                if (listData == null)
                {
                    throw new BusException("维修单号不存在!" + QrCode[1].ToString());
                }
                if (bdata.RealName != listData.RealName)
                {
                    throw new BusException("维修单派工单姓名不符!");
                }
                else
                {
                    base_RepairOrderOK.Id = listData.Id;
                    base_RepairOrderOK.DeviceName = listData.DeviceName;
                    base_RepairOrderOK.Type = listData.Type;
                    base_RepairOrderOK.FaultAnalysis = listData.FaultAnalysis;
                    base_RepairOrderOK.MaintenanceLevel = listData.MaintenanceLevel;
                    base_RepairOrderOK.CreateTime = listData.CreateTime;
                    base_RepairOrderOK.Parentid = listData.Parentid;
                    base_RepairOrderOK.UserId = listData.UserId;
                    base_RepairOrderOK.States = listData.States;
                    string sqlMain = @"SELECT m.`Name` AS MaterName,m.Spec AS MaterSpec,m.`Code` AS Code,S.`Name` AS PB_StoAreaName,R.`Name` AS PB_RackName,
L.`Name` AS PB_LcoationName,IFNULL(SUM(b.OutNum), 0) OutNum FROM TD_OutStorage AS a INNER JOIN TD_OutStorDetail AS b ON b.OutStorId = a.Id INNER JOIN PB_Material AS m ON b.MaterialId = m.Id INNER JOIN PB_Location AS L ON b.LocalId = L.Id INNER JOIN PB_StorArea AS S ON L.AreaId = S.Id INNER JOIN PB_Rack AS R ON L.RackId = R.Id  WHERE a.RefCode='"+ RefCode + "' GROUP BY L.Id,m.Id";
                    var transportbilldetail = await Db.GetListBySqlAsync<MaintainiceOutList>(sqlMain);
                    base_RepairOrderOK.SubData = transportbilldetail;
                    return base_RepairOrderOK;

                }
            }
            else
            {
                throw new BusException("请扫描或输入正确的维修单二维码信息");
            }
        }

        /// <summary>
        /// 维修单点击提交完成操作
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public  async  Task Operationcompleted(string Id)
        {
            var Data = await Db.GetIQueryable<Base_RepairOrderApply>().Where(m=>m.Id==Id).FirstOrDefaultAsync();
            if (Data.States == 3)
            {
                throw new BusException("该维修单已完成");
            }
            else {
                string sqlMain = @" update Base_RepairOrderApply set `States`=3 where Id='" + Id + "' ";
                await ExecuteSqlAsync(sqlMain);
            }
            
        }
    }
    }
